package com.rxyb.trade.utils.yinshang;

import com.alibaba.fastjson.JSON;
import com.rxyb.toolize.RxrcHttpUtils;
import com.rxyb.toolize.VO;
import com.rxyb.toolize.date.DateTime;
import com.rxyb.toolize.date.enums.FormatDate;
import com.rxyb.trade.constants.YinshangConstants;
import com.rxyb.trade.constants.YinshangProperties;
import com.rxyb.trade.db.po.ThirdPayYinshangCfg;
import com.rxyb.trade.gateway.dto.PayOrderReq;
import com.rxyb.trade.gateway.dto.BeanOrderSub;
import com.rxyb.trade.gateway.dto.RefundOrderReq;
import com.rxyb.trade.utils.yinshang.bean.SubOrders;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @coder duyh
 * @date 2020-16-19
 */
@Service
public class YinShangClient {

    @Autowired
    private YinshangProperties yinshangProperties;

    /**
     * 创建渠道交易订单号
     *
     * @param orderNo
     * @return 共24+N位
     */
    public String createTradeOrderNo(String prefix, String orderNo) {
        return prefix + orderNo + VO.radomNumberStr(6);
    }

    /**
     * 下单
     * <p>
     *
     * @param tradeOrderNo
     * @param thirdPayYinshangCfg
     * @param payOrderReq
     * @return
     * @throws Exception
     */
    public String pay(String tradeOrderNo, ThirdPayYinshangCfg thirdPayYinshangCfg, PayOrderReq payOrderReq) throws Exception {
        // 组织请求报文
        JSONObject json = new JSONObject();
        json.put("mid", thirdPayYinshangCfg.getMerId());
        json.put("tid", thirdPayYinshangCfg.getTerminalId());
        json.put("msgType", YinshangConstants.MSG_TYPE_WXPAY);
        json.put("msgSrc", thirdPayYinshangCfg.getMerSrc());
        json.put("instMid", thirdPayYinshangCfg.getInstMid());
        json.put("merOrderId", tradeOrderNo);
        json.put("orderDesc", payOrderReq.getOrderDesc());// 微信
        // 单位：分
        json.put("totalAmount", payOrderReq.getTotalAmount());
        json.put("requestTimestamp", DateTime.getDate(FormatDate.FORMAT_TIME_STR));

        // 交易通知URL
        json.put("notifyUrl", yinshangProperties.getDomainName() + yinshangProperties.getNotifyUrl());
        // 跳转URL
        json.put("returnUrl", yinshangProperties.getDomainName() + yinshangProperties.getReturnUrl());

        // 不要启动担保模式，否则不能退款了
        json.put("secureTransaction", false);

        // 分账模式
        json.put("divisionFlag", true);

        //主账户金额
        json.put("platformAmount", payOrderReq.getTradeAmount());

        if (null != payOrderReq.getSubList()) {
            List<SubOrders> subOrders = new ArrayList<SubOrders>();
            for (BeanOrderSub beanOrderSub : payOrderReq.getSubList()) {
                subOrders.add(new SubOrders(beanOrderSub.getTradeMerId(), beanOrderSub.getTradeAmount()));
            }
            json.put("subOrders", subOrders);

        }

        return YinShangUtils.makeOrderRequest(json, thirdPayYinshangCfg.getMd5Key(), yinshangProperties.getMakeOrderUrl());
    }

    /**
     * 支付查询
     * 注意坑：一个已支付且部分退款的订单，查询结果为TRADE_REFUND，且refundAmount=0
     *
     * @param tradeOrderNo
     * @param thirdPayYinshangCfg
     * @return
     */
    public String query(String tradeOrderNo, ThirdPayYinshangCfg thirdPayYinshangCfg) {
        // 组织请求报文
        JSONObject json = new JSONObject();
        json.put("mid", thirdPayYinshangCfg.getMerId());
        json.put("tid", thirdPayYinshangCfg.getTerminalId());
        json.put("msgType", YinshangConstants.MSG_TYPE_QUERY);
        json.put("msgSrc", thirdPayYinshangCfg.getMerSrc());
        if (VO.isNotBlank(thirdPayYinshangCfg.getInstMid())) {
            json.put("instMid", thirdPayYinshangCfg.getInstMid());
        }
        json.put("merOrderId", tradeOrderNo);

        // 是否要在商户系统下单，看商户需求 createBill()
        json.put("requestTimestamp", DateTime.getDate(FormatDate.FORMAT_TIME_STR));

        Map<String, String> paramsMap = YinShangUtils.jsonToMap(json);
        paramsMap.put("sign", YinShangUtils.makeSign(thirdPayYinshangCfg.getMd5Key(), paramsMap));
        System.out.println("paramsMap：" + paramsMap);

        String strReqJsonStr = JSON.toJSONString(paramsMap);
        System.out.println("strReqJsonStr:" + strReqJsonStr);

        String resultStr = RxrcHttpUtils.executePost(yinshangProperties.getPostUrl(), strReqJsonStr);
        return resultStr;
    }

    /**
     * 关闭订单
     *
     * @param tradeOrderNo
     * @param thirdPayYinshangCfg
     * @return
     */
    public String close(String tradeOrderNo, ThirdPayYinshangCfg thirdPayYinshangCfg) {
        // 组织请求报文
        JSONObject json = new JSONObject();
        json.put("mid", thirdPayYinshangCfg.getMerId());
        json.put("tid", thirdPayYinshangCfg.getTerminalId());
        json.put("msgType", YinshangConstants.MSG_TYPE_CLOSE);
        json.put("msgSrc", thirdPayYinshangCfg.getMerSrc());
        if (VO.isNotBlank(thirdPayYinshangCfg.getInstMid())) {
            json.put("instMid", thirdPayYinshangCfg.getInstMid());
        }
        json.put("merOrderId", tradeOrderNo);

        // 是否要在商户系统下单，看商户需求 createBill()
        json.put("requestTimestamp", DateTime.getDate(FormatDate.FORMAT_TIME_STR));

        Map<String, String> paramsMap = YinShangUtils.jsonToMap(json);
        paramsMap.put("sign", YinShangUtils.makeSign(thirdPayYinshangCfg.getMd5Key(), paramsMap));
        System.out.println("paramsMap：" + paramsMap);

        String strReqJsonStr = JSON.toJSONString(paramsMap);
        System.out.println("strReqJsonStr:" + strReqJsonStr);

        String resultStr = RxrcHttpUtils.executePost(yinshangProperties.getPostUrl(), strReqJsonStr);
        return resultStr;
    }

    /**
     * 退款
     * <p>
     *
     * @param thirdPayYinshangCfg
     * @param refundOrderReq
     * @param tradeOrderNo
     * @param refundOrderNo
     * @return
     */
    public String refund(ThirdPayYinshangCfg thirdPayYinshangCfg, RefundOrderReq refundOrderReq, String tradeOrderNo, String refundOrderNo) {
        // 组织请求报文
        JSONObject json = new JSONObject();
        json.put("mid", thirdPayYinshangCfg.getMerId());
        json.put("tid", thirdPayYinshangCfg.getTerminalId());
        json.put("msgType", YinshangConstants.MSG_TYPE_REFUND);
        json.put("msgSrc", thirdPayYinshangCfg.getMerSrc());
        if (VO.isNotBlank(thirdPayYinshangCfg.getInstMid())) {
            json.put("instMid", thirdPayYinshangCfg.getInstMid());
        }
        json.put("merOrderId", tradeOrderNo);
        json.put("refundOrderId", refundOrderNo);

        // 是否要在商户系统下单，看商户需求 createBill()

        // 退款金额
        json.put("refundAmount", refundOrderReq.getTotalAmount());
        // 主账户退款金额
        json.put("platformAmount", refundOrderReq.getTradeAmount());

        json.put("requestTimestamp", DateTime.getDate(FormatDate.FORMAT_TIME_STR));

        if (null != refundOrderReq.getSubList()) {
            List<SubOrders> subOrders = new ArrayList<SubOrders>();
            for (BeanOrderSub beanOrderSub : refundOrderReq.getSubList()) {
                subOrders.add(new SubOrders(beanOrderSub.getTradeMerId(), beanOrderSub.getTradeAmount()));
            }
            json.put("subOrders", subOrders);
        }


        Map<String, String> paramsMap = YinShangUtils.jsonToMap(json);

        System.out.println("paramsMap：" + paramsMap);

        json.put("sign", YinShangUtils.makeSign(thirdPayYinshangCfg.getMd5Key(), paramsMap));
        String strReqJsonStr = json.toString();

        String resultStr = RxrcHttpUtils.executePost(yinshangProperties.getPostUrl(), strReqJsonStr);
        System.out.println("strReqJsonStr:" + strReqJsonStr + "<=====>resultStr:" + resultStr);
        return resultStr;
    }

}
